IAT 的內容與 windows 核心、記憶體、DLL 有關,它是一個表格,紀錄程序使用庫中的那些函數。
IMPORT Directory Table
,這個結構記錄 PE 檔案要引入那些 libary。並且位於 PE body 中 ( 不是 head ),但查找信息在 PE Head 裡面,詳細位於 IMAGE_OPTIONAL_HEADER.DataDirectory[1].VirtualAddress 就是 IMAGE_IMPORT_DESCRIPTOR
的起始位置。
在 winnt.h
的紀錄 :
一個文件往往要導入多個 libary,要導入多少個 libary 決定於有多少個 IMAGE_IMPORT_DESCRIPTOR
結構,而這些結構組成一個 Table
,這個 Table
以 NULL
(0x00
) 來結束。
其中,IMAGE_IMPORT_DESCRIPTOR
(IID
) 的重要成員 :
OrigninalFirstThunk
: INT ( Import name table )
的位置 ( RVA )Name
: Libary 的名稱字串的位置 ( RVA )FirstThunk
: IAT ( Import address table )
的位置 ( RVA )下圖以 user32.dll
為範例 :
輸入順序 :
IID
的 Name
成員,取得字串 "USER32.DLL”
LoadLibary(”USER32.DLL”);
OrigninalFirstThunk
,取得 INT
位置IMAGE_IMPORT_BY_NAME
的 Hint
或 Name
取得函數得起始位置。IID
的 FirstThunk
成員值, 獲得 IAT
位置。IAT
中IAT
位置指向值是 NULL
使用 PE viewer 查看 Import Function
:
這個程式一開始是在 Win XP 環境上製成的,但在我的 Win 10 上也可以正常運行。這是因為 PE loader 在執行時會把位置改成相應 API 的起始位置。
libary 是為了方便其他程式調用他的函式而集中有關函數的文件。像是 Win32 API
中 kernel32.dll
是最核心的庫文件。而 EAT
使其他程序可以透過 IMAGE_EXPORT_DIRECTORY
來得到這個文件的函數起始位置在哪裡,也只有使用這種方法才能取的 EAT
結構。
它的定義位置在於 _IMAGE_OPTIONAL_HEADER.DataDirectory[0].VirtualAddress
,而定義於 winnt.h
中結構如下 :
利用 PE bear 觀察結構在 kernel32.dll
中:
NumberOfNames
: 輸出有名字的函數個數
Number of Function
: 輸出函數個數
AddressOfFunction
: 輸出的函數位置組數
AddressOfNames
: 輸出函數名稱位置組數
AddressOfNameOrdinals
: Ordinal
位置組數以圖片為範例,看看程序上是甚麼從 Foo.DLL
中取得 AnotherExport
( 中間那一個函數 )的 :
Address of name
取得名稱組AnotherExport
字串來確認是否為需要的函數,結果為第二個。AddressOfNameOrdinals
的第二個取得 Ordinal
值為二 ( 有可能不是每次都是第二個,有些函數沒有名字會導致 Ordinal
值往後排 ) 。AddressOfFunctions
轉到 函數位置表
( 也就是 EAT
)。Ordinal
值作為索引,就可以取得函數的起始位置 !